home *** CD-ROM | disk | FTP | other *** search
/ Isometric Game Programming with DirectX 7.0 / Isometric Game Programming.iso / source / chapter7 / isohex7_2 / isohex7_2.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-24  |  10.9 KB  |  441 lines

  1. /*****************************************************************************
  2. IsoHex7_2.cpp
  3. Ernest S. Pazera
  4. 24MAY2000
  5. Start a WIN32 Application Workspace, add in this file
  6. Needs ddraw.lib and dxguid.lib
  7. Needs GDICanvas.h/cpp
  8. Needs DDFuncs.h/cpp
  9. *****************************************************************************/
  10.  
  11. //////////////////////////////////////////////////////////////////////////////
  12. //INCLUDES
  13. //////////////////////////////////////////////////////////////////////////////
  14. #define WIN32_LEAN_AND_MEAN  
  15.  
  16. #include <windows.h>   
  17. #include "GDICanvas.h"
  18. #include "ddraw.h"
  19. #include "DDFuncs.h"
  20.  
  21. //////////////////////////////////////////////////////////////////////////////
  22. //DEFINES
  23. //////////////////////////////////////////////////////////////////////////////
  24. //name for our window class
  25. #define WINDOWCLASS "ISOHEX7"
  26. //title of the application
  27. #define WINDOWTITLE "IsoHex 7-2"
  28.  
  29. //////////////////////////////////////////////////////////////////////////////
  30. //PROTOTYPES
  31. //////////////////////////////////////////////////////////////////////////////
  32. bool Prog_Init();//game data initalizer
  33. void Prog_Loop();//main game loop
  34. void Prog_Done();//game clean up
  35.  
  36. //enumeration functions
  37. HRESULT WINAPI EnumModesCallbackCount(LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext);
  38. HRESULT WINAPI EnumModesCallbackList(LPDDSURFACEDESC2 lpDDSurfaceDesc,LPVOID lpContext);
  39.  
  40. //////////////////////////////////////////////////////////////////////////////
  41. //GLOBALS
  42. //////////////////////////////////////////////////////////////////////////////
  43. HINSTANCE hInstMain=NULL;//main application handle
  44. HWND hWndMain=NULL;//handle to our main window
  45. //IDirectDraw7 Pointer
  46. LPDIRECTDRAW7 lpdd=NULL;
  47.  
  48. //gdicanvas
  49. CGDICanvas gdicBall;
  50.  
  51. //surfaces
  52. LPDIRECTDRAWSURFACE7 lpddsPrime=NULL;
  53. LPDIRECTDRAWSURFACE7 lpddsBack=NULL;
  54. LPDIRECTDRAWSURFACE7 lpddsBall=NULL;
  55.  
  56. //clipper
  57. LPDIRECTDRAWCLIPPER lpddclip=NULL;
  58.  
  59. //size of the display
  60. DWORD dwDisplayWidth=0;
  61. DWORD dwDisplayHeight=0;
  62.  
  63. //position of the ball
  64. POINT ptBallPosition[2];
  65. POINT ptLastPosition[2];
  66. //velocity of the ball
  67. POINT ptBallVelocity[2];
  68.  
  69. //screen coordinate corresponding to the upper left of the client area
  70. POINT ptPrimeBlt;
  71.  
  72. //paused mode
  73. bool bPaused=false;
  74.  
  75. //////////////////////////////////////////////////////////////////////////////
  76. //WINDOWPROC
  77. //////////////////////////////////////////////////////////////////////////////
  78. LRESULT CALLBACK TheWindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
  79. {
  80.     //which message did we get?
  81.     switch(uMsg)
  82.     {
  83.     case WM_MOVE:
  84.         {
  85.             //set primeblit point to client 0,0
  86.             ptPrimeBlt.x=0;
  87.             ptPrimeBlt.y=0;
  88.  
  89.             //convert to screen coordinates
  90.             ClientToScreen(hwnd,&ptPrimeBlt);
  91.  
  92.             //handled... return 0
  93.             return(0);
  94.         }break;
  95.     case WM_ACTIVATEAPP:
  96.         {
  97.             if(wParam)
  98.             {
  99.                 if(bPaused)
  100.                 {
  101.                     //being activated
  102.                     bPaused=false;
  103.  
  104.                     //restore all surfaces
  105.                     lpdd->RestoreAllSurfaces();
  106.  
  107.                     //clear out back buffer
  108.                     DDBLTFX ddbltfx;
  109.                     DDBLTFX_ColorFill(&ddbltfx,0);
  110.                     lpddsBack->Blt(NULL,NULL,NULL,DDBLT_WAIT | DDBLT_COLORFILL,&ddbltfx);
  111.  
  112.                     //reload ball images
  113.                     LPDDS_ReloadFromFile(lpddsBall,"IsoHex6_4.bmp");
  114.                 }
  115.             }
  116.             else
  117.             {
  118.                 //being deactivated
  119.                 bPaused=true;
  120.             }
  121.         }break;
  122.     case WM_KEYDOWN:
  123.         {
  124.             //check for escape key
  125.             if(wParam==VK_ESCAPE)
  126.             {
  127.                 DestroyWindow(hWndMain);
  128.             }
  129.  
  130.             return(0);//handled message
  131.         }break;
  132.     case WM_DESTROY://the window is being destroyed
  133.         {
  134.  
  135.             //tell the application we are quitting
  136.             PostQuitMessage(0);
  137.  
  138.             //handled message, so return 0
  139.             return(0);
  140.  
  141.         }break;
  142.     case WM_PAINT://the window needs repainting
  143.         {
  144.             //a variable needed for painting information
  145.             PAINTSTRUCT ps;
  146.             
  147.             //start painting
  148.             HDC hdc=BeginPaint(hwnd,&ps);
  149.  
  150.             /////////////////////////////
  151.             //painting code would go here
  152.             /////////////////////////////
  153.  
  154.             //end painting
  155.             EndPaint(hwnd,&ps);
  156.                         
  157.             //handled message, so return 0
  158.             return(0);
  159.         }break;
  160.     }
  161.  
  162.     //pass along any other message to default message handler
  163.     return(DefWindowProc(hwnd,uMsg,wParam,lParam));
  164. }
  165.  
  166.  
  167. //////////////////////////////////////////////////////////////////////////////
  168. //WINMAIN
  169. //////////////////////////////////////////////////////////////////////////////
  170. int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
  171. {
  172.     //assign instance to global variable
  173.     hInstMain=hInstance;
  174.  
  175.     //create window class
  176.     WNDCLASSEX wcx;
  177.  
  178.     //set the size of the structure
  179.     wcx.cbSize=sizeof(WNDCLASSEX);
  180.  
  181.     //class style
  182.     wcx.style=CS_OWNDC | CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  183.  
  184.     //window procedure
  185.     wcx.lpfnWndProc=TheWindowProc;
  186.  
  187.     //class extra
  188.     wcx.cbClsExtra=0;
  189.  
  190.     //window extra
  191.     wcx.cbWndExtra=0;
  192.  
  193.     //application handle
  194.     wcx.hInstance=hInstMain;
  195.  
  196.     //icon
  197.     wcx.hIcon=LoadIcon(NULL,IDI_APPLICATION);
  198.  
  199.     //cursor
  200.     wcx.hCursor=LoadCursor(NULL,IDC_ARROW);
  201.  
  202.     //background color
  203.     wcx.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
  204.  
  205.     //menu
  206.     wcx.lpszMenuName=NULL;
  207.  
  208.     //class name
  209.     wcx.lpszClassName=WINDOWCLASS;
  210.  
  211.     //small icon
  212.     wcx.hIconSm=NULL;
  213.  
  214.     //register the window class, return 0 if not successful
  215.     if(!RegisterClassEx(&wcx)) return(0);
  216.  
  217.     //create main window
  218.     hWndMain=CreateWindowEx(0,WINDOWCLASS,WINDOWTITLE, WS_BORDER | WS_CAPTION | WS_SYSMENU | WS_VISIBLE,0,0,640,480,NULL,NULL,hInstMain,NULL);
  219.  
  220.     //error check
  221.     if(!hWndMain) return(0);
  222.  
  223.     //if program initialization failed, then return with 0
  224.     if(!Prog_Init()) return(0);
  225.  
  226.     //message structure
  227.     MSG msg;
  228.  
  229.     //message pump
  230.     for(;;)    
  231.     {
  232.         //look for a message
  233.         if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
  234.         {
  235.             //there is a message
  236.  
  237.             //check that we arent quitting
  238.             if(msg.message==WM_QUIT) break;
  239.             
  240.             //translate message
  241.             TranslateMessage(&msg);
  242.  
  243.             //dispatch message
  244.             DispatchMessage(&msg);
  245.         }
  246.  
  247.         //run main game loop
  248.         Prog_Loop();
  249.     }
  250.     
  251.     //clean up program data
  252.     Prog_Done();
  253.  
  254.     //return the wparam from the WM_QUIT message
  255.     return(msg.wParam);
  256. }
  257.  
  258. //////////////////////////////////////////////////////////////////////////////
  259. //INITIALIZATION
  260. //////////////////////////////////////////////////////////////////////////////
  261. bool Prog_Init()
  262. {
  263.     //create direct draw object
  264.     lpdd=LPDD_Create(hWndMain,DDSCL_NORMAL);
  265.  
  266.     //check the display bpp
  267.     DDSURFACEDESC2 ddsd;
  268.     DDSD_Clear(&ddsd);
  269.     lpdd->GetDisplayMode(&ddsd);
  270.     if(ddsd.ddpfPixelFormat.dwRGBBitCount<16)
  271.     {
  272.         if(MessageBox(hWndMain,"This demo is designed for hi-color modes.  Continuing in your current display mode may not look as good. Do you wish to continue?","Continue?",MB_YESNO)==IDNO)
  273.         {
  274.             //do not continue
  275.             return(false);
  276.         }
  277.     }
  278.  
  279.     //retrieve client rectangle
  280.     RECT rcClient;
  281.     GetClientRect(hWndMain,&rcClient);
  282.  
  283.     //keep display width and height in global variables
  284.     dwDisplayWidth=rcClient.right;
  285.     dwDisplayHeight=rcClient.bottom;
  286.  
  287.     //create the primary surface with no back buffers
  288.     lpddsPrime=LPDDS_CreatePrimary(lpdd,0);
  289.  
  290.     //retrieve back buffer
  291.     lpddsBack=LPDDS_CreateOffscreen(lpdd,dwDisplayWidth,dwDisplayHeight);
  292.  
  293.     //do an initial clearing out of the back buffer
  294.     DDBLTFX ddbltfx;
  295.     DDBLTFX_ColorFill(&ddbltfx,0);
  296.  
  297.     //do a color fill
  298.     lpddsBack->Blt(NULL,NULL,NULL,DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx);
  299.  
  300.     //create clipper
  301.     lpdd->CreateClipper(0,&lpddclip,NULL);
  302.  
  303.     //set clipper window
  304.     lpddclip->SetHWnd(0,hWndMain);
  305.  
  306.     //attach clipper
  307.     lpddsPrime->SetClipper(lpddclip);
  308.  
  309.     //load in the ball image
  310.     gdicBall.Load(NULL,"IsoHex7_2.bmp");
  311.  
  312.     //create an offscreen surface to contain the ball
  313.     lpddsBall=LPDDS_LoadFromFile(lpdd,"IsoHex7_2.bmp");
  314.  
  315.     //create a black color key
  316.     LPDDS_SetSrcColorKey(lpddsBall,0);
  317.  
  318.     //initialize ball position and velocity
  319.     ptBallPosition[0].x=0;
  320.     ptBallPosition[0].y=0;
  321.     ptLastPosition[0].x=0;
  322.     ptLastPosition[0].y=0;
  323.     ptBallPosition[1].x=0;
  324.     ptBallPosition[1].y=0;
  325.     ptLastPosition[1].x=0;
  326.     ptLastPosition[1].y=0;
  327.  
  328.     ptBallVelocity[0].x=4;
  329.     ptBallVelocity[0].y=2;
  330.     ptBallVelocity[1].x=2;
  331.     ptBallVelocity[1].y=4;
  332.  
  333.     //setup the primary blit position
  334.     ptPrimeBlt.x=0;
  335.     ptPrimeBlt.y=0;
  336.     ClientToScreen(hWndMain,&ptPrimeBlt);
  337.  
  338.     return(true);//return success
  339. }
  340.  
  341. //////////////////////////////////////////////////////////////////////////////
  342. //CLEANUP
  343. //////////////////////////////////////////////////////////////////////////////
  344. void Prog_Done()
  345. {    
  346.     //clean up clipper
  347.     LPDDCLIP_Release(&lpddclip);
  348.  
  349.     //clean up ball surface
  350.     LPDDS_Release(&lpddsBall);
  351.  
  352.     //clean up "back buffer"
  353.     LPDDS_Release(&lpddsBack);
  354.         
  355.     //clean up primary surface
  356.     LPDDS_Release(&lpddsPrime);
  357.  
  358.     //clean up the dd pointer
  359.     LPDD_Release(&lpdd);
  360.  
  361.     //clean up gdicanvas
  362.     gdicBall.Destroy();
  363.  
  364. }
  365.  
  366. //////////////////////////////////////////////////////////////////////////////
  367. //MAIN GAME LOOP
  368. //////////////////////////////////////////////////////////////////////////////
  369. void Prog_Loop()
  370. {
  371.     //if paused, return without doing anything
  372.     if(bPaused) return;
  373.  
  374.     int index;
  375.  
  376.     for(index=0;index<2;index++)
  377.     {
  378.  
  379.  
  380.     //set up rectangle for filling
  381.     RECT rcFill;
  382.     SetRect(&rcFill,ptLastPosition[index].x,ptLastPosition[index].y,ptLastPosition[index].x+gdicBall.GetWidth(),ptLastPosition[index].y+gdicBall.GetHeight());
  383.  
  384.     //set up a ddbltfx
  385.     DDBLTFX ddbltfx;
  386.     DDBLTFX_ColorFill(&ddbltfx,0);
  387.  
  388.     //blt the color fill to the back buffer
  389.     lpddsBack->Blt(&rcFill,NULL,NULL,DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx);
  390.     }
  391.  
  392.     for(index=0;index<2;index++)
  393.     {
  394.     //set up source and destination rects for blitting the ball
  395.     RECT rcSrc;
  396.     RECT rcDst;
  397.  
  398.     SetRect(&rcSrc,0,0,gdicBall.GetWidth(),gdicBall.GetHeight());
  399.     CopyRect(&rcDst,&rcSrc);
  400.     OffsetRect(&rcDst,ptBallPosition[index].x,ptBallPosition[index].y);
  401.  
  402.     //blit the ball
  403.     lpddsBack->Blt(&rcDst,lpddsBall,&rcSrc,DDBLT_WAIT | DDBLT_KEYSRC, NULL);
  404.  
  405.     //copy current position of ball to old position
  406.     ptLastPosition[index]=ptBallPosition[index];
  407.  
  408.     //move the ball
  409.     ptBallPosition[index].x+=ptBallVelocity[index].x;
  410.     ptBallPosition[index].y+=ptBallVelocity[index].y;
  411.  
  412.     //bounds checking
  413.     //left side
  414.     if(ptBallPosition[index].x<=0) ptBallVelocity[index].x=abs(ptBallVelocity[index].x);
  415.     //top side
  416.     if(ptBallPosition[index].y<=0) ptBallVelocity[index].y=abs(ptBallVelocity[index].y);
  417.     //right side
  418.     if(ptBallPosition[index].x>=(int)dwDisplayWidth-gdicBall.GetWidth()) ptBallVelocity[index].x=-abs(ptBallVelocity[index].x);
  419.     //bottom side
  420.     if(ptBallPosition[index].y>=(int)dwDisplayHeight-gdicBall.GetHeight()) ptBallVelocity[index].y=-abs(ptBallVelocity[index].y);
  421.     }
  422.  
  423.     //copy from "back buffer" onto primary
  424.     //declare rectangles
  425.     RECT rcSrc;
  426.     RECT rcDst;
  427.  
  428.     //set up source rectangle
  429.     SetRect(&rcSrc,0,0,dwDisplayWidth,dwDisplayHeight);
  430.  
  431.     //copy source rect to destination rect
  432.     CopyRect(&rcDst,&rcSrc);
  433.  
  434.     //offset by the screen coordinate of the window's client area
  435.     OffsetRect(&rcDst,ptPrimeBlt.x,ptPrimeBlt.y);
  436.  
  437.     //performa the blit
  438.     lpddsPrime->Blt(&rcDst,lpddsBack,&rcSrc,DDBLT_WAIT,NULL);
  439. }
  440.  
  441.